/*
By Zhe Chen
This was part of the basic graphics library that we did not have time to wire up to the interpretor.   It gives the user the functionality to draw basic items such as lines, points, shapes, etc in order to create more 
complex graph types.   	
*/

import java.util.HashMap;
import java.util.ArrayList;

//This is the class that has the functions that takes in a hashmap, then iterates through it and grabs all the arguments for each drawing type, then calls the corresponding drawing functions with those arguments set.
public class writeImage{
		
	public writeImage(){
		
	}
	
	 public void write_image(String filename, HashMap<String, GraphrDataType> c)throws Exception{
		//This part grabs the canvas function calls and gets the according arguments.
		ArrayList<GraphrDataType> can_array = ((GraphrArray)(c.get("add_canvas"))).getArray();
		HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)can_array.get(0)).getHashMap();
		
		int w = ((GraphrNumber)temp.get("width")).toInt();
		int h = ((GraphrNumber)temp.get("height")).toInt();
		String b;
		if (temp.containsKey("background")){
			b = ((GraphrString)temp.get("background")).toString();;
		}
		else {
			b = "0x000000";
		}
		DrawCanvas newCanvas = new DrawCanvas(w, h, b);
		
		//Calls each function that takes an ArrayList of each differenet type of function call.   
		if (c.containsKey("add_circle"))			init_circles(newCanvas, ((GraphrArray)c.get("add_circle")).getArray());
		if (c.containsKey("add_rectangle"))			init_rectangles(newCanvas, ((GraphrArray)c.get("add_rectangle")).getArray());
		if (c.containsKey("add_line"))				init_lines(newCanvas, ((GraphrArray)c.get("add_line")).getArray());
		if (c.containsKey("add_line_from_points"))	init_lines_p(newCanvas, ((GraphrArray)c.get("add_line_from_points")).getArray());
		if (c.containsKey("add_label"))				init_labels(newCanvas, ((GraphrArray)c.get("add_label")).getArray());
		if (c.containsKey("add_data_points"))		init_points(newCanvas, ((GraphrArray)c.get("add_data_points")).getArray());
		newCanvas.write(filename);		//Finally, calls the function to write the file.
	}
	
	//This function generates a Hashmap with some basic drawing functions used, as a test.
	 public HashMap<String, GraphrDataType> sampleCanvas(){
		 GraphrAssociativeArray picture = new GraphrAssociativeArray();
		 GraphrArray can_array = new GraphrArray();
		 GraphrArray line_array = new GraphrArray();
		 GraphrArray line_point_array = new GraphrArray();
		 GraphrArray point_array = new GraphrArray();
		 GraphrArray circle_array = new GraphrArray();
		 GraphrArray rectangle_array = new GraphrArray();
		 GraphrArray label_array = new GraphrArray();
		
		 GraphrAssociativeArray can = new GraphrAssociativeArray();
		 can.put("width", new GraphrNumber(500));
		 can.put("height", new GraphrNumber(400));
		 can.put("background", new GraphrString("0x0345F1"));
		 can_array.push(can);
		
		 GraphrAssociativeArray line1 = new GraphrAssociativeArray();
		 line1.put("canvas", new GraphrNumber(0));
		 line1.put("x", new GraphrNumber(50));
		 line1.put("y", new GraphrNumber(50));
		 line1.put("width", new GraphrNumber(2));
		 line1.put("length", new GraphrNumber(450));
		 line1.put("direction", new GraphrString("vertical"));
		 line1.put("color", new GraphrString("0x000000"));
		 line_array.push(line1);
		 GraphrAssociativeArray line2 = new GraphrAssociativeArray();
		 line2.put("canvas", new GraphrNumber(0));
		 line2.put("x", new GraphrNumber(50));
		 line2.put("y", new GraphrNumber(90));
		 line2.put("length", new GraphrNumber(350));
		 line_array.push(line2);
		
		GraphrAssociativeArray linep1 = new GraphrAssociativeArray();
		linep1.put("start_x", new GraphrNumber(50));
		linep1.put("start_y", new GraphrNumber(50));
		linep1.put("end_x", new GraphrNumber(60));
		linep1.put("end_y", new GraphrNumber(400));
		linep1.put("width", new GraphrNumber(5));
		linep1.put("color", new GraphrString("0x000000"));
		line_point_array.push(linep1);
		GraphrAssociativeArray linep2 = new GraphrAssociativeArray();
		linep2.put("start_x", new GraphrNumber(50));
		linep2.put("start_y", new GraphrNumber(50));
		linep2.put("end_x", new GraphrNumber(70));
		linep2.put("end_y", new GraphrNumber(100));
		line_point_array.push(linep2);
		
		
		GraphrAssociativeArray point1 = new GraphrAssociativeArray();
		point1.put("x", new GraphrNumber(300));
		point1.put("y", new GraphrNumber(300));
		point1.put("width", new GraphrNumber(5));
		point1.put("color", new GraphrString("0x000000"));
		point_array.push(point1);
		GraphrAssociativeArray point2 = new GraphrAssociativeArray();
		point2.put("x", new GraphrNumber(100));
		point2.put("y", new GraphrNumber(100));
		point_array.push(point2);
		//System.out.println(add_points_list);
		
		GraphrAssociativeArray circle1 = new GraphrAssociativeArray();
		circle1.put("x", new GraphrNumber(300));
		circle1.put("y", new GraphrNumber(300));
		circle1.put("radius", new GraphrNumber(15));
		circle1.put("width", new GraphrNumber(7));
		circle1.put("border_color", new GraphrString("0x000000"));
		circle1.put("background_color", new GraphrString("0xFFFFFF"));
		circle_array.push(circle1);
		GraphrAssociativeArray circle2 = new GraphrAssociativeArray();
		circle2.put("x", new GraphrNumber(250));
		circle2.put("y", new GraphrNumber(290));
		circle2.put("radius", new GraphrNumber(7));
		circle_array.push(circle2);
		
		GraphrAssociativeArray rec1 = new GraphrAssociativeArray();
		rec1.put("x", new GraphrNumber(350));
		rec1.put("y", new GraphrNumber(150));
		rec1.put("height", new GraphrNumber(50));
		rec1.put("across", new GraphrNumber(50));
		rec1.put("width", new GraphrNumber(3));
		rec1.put("border_color", new GraphrString("0x000000"));
		rec1.put("background_color", new GraphrString("0xFFFFFF"));
		rectangle_array.push(rec1);
		GraphrAssociativeArray rec2 = new GraphrAssociativeArray();
		rec2.put("x", new GraphrNumber(400));
		rec2.put("y", new GraphrNumber(390));
		rec2.put("height", new GraphrNumber(50));
		rec2.put("across", new GraphrNumber(80));
		rectangle_array.push(rec2);
		
		GraphrAssociativeArray lab1 = new GraphrAssociativeArray();
		lab1.put("x", new GraphrNumber(200));
		lab1.put("y", new GraphrNumber(200));
		lab1.put("direction", new GraphrString("vertical"));
		lab1.put("size", new GraphrNumber(27));
		lab1.put("text", new GraphrString("HOLY MOLY THIS WORKS!"));
		label_array.push(lab1);
		GraphrAssociativeArray lab2 = new GraphrAssociativeArray();
		lab2.put("x", new GraphrNumber(100));
		lab2.put("y", new GraphrNumber(100));
		lab2.put("text", new GraphrString("GOD LIKE!"));
		label_array.push(lab2);
		
		picture.put("add_canvas", can_array);
		picture.put("add_line", line_array);
		picture.put("add_line_from_points", line_point_array);
		picture.put("add_data_points", point_array);
		picture.put("add_circle", circle_array);
		picture.put("add_rectangle", rectangle_array);
		picture.put("add_label", label_array);
		
		//System.out.println(canvas);
		HashMap<String, GraphrDataType> temp = picture.getHashMap();
		return temp;
	}
	
	//Functions to read each type of drawing function.
	private void init_lines(DrawCanvas c, ArrayList<GraphrDataType> r){
		int size = r.size();
		int x;
		int y;
		int width;
		int length;
		String direction;
		String color;
		for (int i = 0; i < size; i++){
			HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)r.get(i)).getHashMap();
			x = ((GraphrNumber)temp.get("x")).toInt();
			y = ((GraphrNumber)temp.get("y")).toInt();
			length = ((GraphrNumber)temp.get("length")).toInt();
			width = 2;
			direction = "horizontal";
			color = "0x000000";
			if (temp.containsKey("width"))	width = ((GraphrNumber)temp.get("width")).toInt();
			if (temp.containsKey("direction"))	direction = ((GraphrString)temp.get("direction")).toString();
			if (temp.containsKey("color"))	color = ((GraphrString)temp.get("color")).toString();
			
			c.add_line(x, y, length, (float)width, direction, color); 
		}
	}

	private void init_lines_p(DrawCanvas c, ArrayList<GraphrDataType> r){
		int size = r.size();
		int sx;
		int sy;
		int ex;
		int ey;
		float width;
		String color;
		for (int i = 0; i < size; i++){
			HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)r.get(i)).getHashMap();
			sx = ((GraphrNumber)temp.get("start_x")).toInt();
			sy = ((GraphrNumber)temp.get("start_y")).toInt();
			ex = ((GraphrNumber)temp.get("end_x")).toInt();
			ey = ((GraphrNumber)temp.get("end_y")).toInt();
			width = 2;
			color = "0x000000";
			if (temp.containsKey("width"))	width = (float)((GraphrNumber)temp.get("width")).toInt();
			if (temp.containsKey("color"))	color = ((GraphrString)temp.get("color")).toString();
			
			c.add_line_from_points(sx, sy, ex, ey, width, color); 
		}
	}
	
	private void init_points(DrawCanvas c, ArrayList<GraphrDataType> r){
		int size = r.size();
		int x;
		int y;
		int width;
		String color;
		for (int i = 0; i < size; i++){
			HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)r.get(i)).getHashMap();
			x = ((GraphrNumber)temp.get("x")).toInt();
			y = ((GraphrNumber)temp.get("y")).toInt();
			width = 2;
			color = "0x000000";
			if (temp.containsKey("width"))	width = ((GraphrNumber)temp.get("width")).toInt();
			if (temp.containsKey("color"))	color = ((GraphrString)temp.get("color")).toString();
			
			c.add_points(x, y, width, color); 
		}
	}
	
	private void init_circles(DrawCanvas c, ArrayList<GraphrDataType> r){
		int size = r.size();
		int x;
		int y;
		int radius;
		float width;
		String colorb;
		String colorf;
		for (int i = 0; i < size; i++){
			HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)r.get(i)).getHashMap();
			x = ((GraphrNumber)temp.get("x")).toInt();
			y = ((GraphrNumber)temp.get("y")).toInt();
			radius = ((GraphrNumber)temp.get("radius")).toInt();
			width = 2;
			colorb = "0x000000";
			colorf = "0xFFFFFF";
			if (temp.containsKey("width"))	width = (float)((GraphrNumber)temp.get("width")).toInt();
			if (temp.containsKey("border_color"))	colorb = ((GraphrString)temp.get("border_color")).toString();
			if (temp.containsKey("background_color"))	colorf = ((GraphrString)temp.get("background_color")).toString();
			
			c.add_circle(x, y, radius,  width, colorb, colorf); 
		}
	}
	
	private void init_rectangles(DrawCanvas c, ArrayList<GraphrDataType> r){
		int size = r.size();
		int x;
		int y;
		int height;
		int across;
		float width;
		String colorb;
		String colorf;
		for (int i = 0; i < size; i++){
			HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)r.get(i)).getHashMap();
			x = ((GraphrNumber)temp.get("x")).toInt();
			y = ((GraphrNumber)temp.get("y")).toInt();
			height = ((GraphrNumber)temp.get("height")).toInt();
			across = ((GraphrNumber)temp.get("across")).toInt();
			width = 2;
			colorb = "0x000000";
			colorf = "0xFFFFFF";
			if (temp.containsKey("width"))	width = (float)((GraphrNumber)temp.get("width")).toInt();
			if (temp.containsKey("border_color"))	colorb = ((GraphrString)temp.get("border_color")).toString();
			if (temp.containsKey("background_color"))	colorf = ((GraphrString)temp.get("background_color")).toString();
			
			c.add_rectangle(x, y, height, across,  width, colorb, colorf); 
		}
	}
	
	private void init_labels(DrawCanvas c, ArrayList<GraphrDataType> r)throws Exception{
		int size = r.size();
		int x;
		int y;
		String direction;
		int fontsize;
		String text;
		for (int i = 0; i < size; i++){
			HashMap<String, GraphrDataType> temp = ((GraphrAssociativeArray)r.get(i)).getHashMap();
			x = ((GraphrNumber)temp.get("x")).toInt();
			y = ((GraphrNumber)temp.get("y")).toInt();
			text = ((GraphrString)temp.get("text")).toString();
			direction = "horizontal";
			fontsize = 10;
			if (temp.containsKey("size"))	fontsize = ((GraphrNumber)temp.get("size")).toInt();
			if (temp.containsKey("direction"))	direction = ((GraphrString)temp.get("direction")).toString();
			
			c.add_label(x, y, direction, fontsize, text); 
		}
	}
	
	
}